#ifndef NET_TCPSERVER_H
#define NET_TCPSERVER_H

#include "Sockaddr.h"
#include "callback.h"
#include "eventloop/EventloopThreadFwd.h"
#include "utility/Noncopyable.h"

#include <atomic>
#include <map>

class Acceptor;
class Eventloop;
class EventloopThreadPool;
class Socket;

class TCPServer {
public:
    TCPServer(Eventloop &loop, const Sockaddr &addr, const std::string &name, bool reusePort = false);
    ~TCPServer();

    std::size_t connection_size() const { return _connections.size(); }
    const std::string &name() const { return _name; }
    

    void set_connection_callback(const ConnectionCallback &callback)
    { _connectionCallback = callback; }
    void set_message_callback(const MessageCallback &callback)
    { _messageCallback = callback; }
    void set_init_func(const EventloopThreadInitFunc &func) 
    { _initFunc = func; }
    void set_drain_callback(const DrainCallback &callback) {
        _drainCallback = callback;
    }
    void set_thread_count(std::size_t count) const;

    void start();
    void stop();

private:
    NONCOPYABLE(TCPServer);
    
    void _close_callback(const TCPConnectionPtr &connection);
    void _new_connection_callback(std::unique_ptr<Socket> &&socket, const Sockaddr &peer);

    std::map<std::string, TCPConnectionPtr> _connections;
    
    const std::string _IPport;
    const std::string _name;
    ConnectionCallback _connectionCallback;
    DrainCallback _drainCallback;
    EventloopThreadInitFunc _initFunc;
    MessageCallback _messageCallback;
    const std::shared_ptr<EventloopThreadPool> _pool;
    Eventloop &_loop;
    std::unique_ptr<Acceptor> _acceptor;
    int _connectionID;
    std::atomic<bool> _started;
    

};


#endif